package com.njmaomao.gj.pyot.config;

import com.njmaomao.gj.pyot.common.ResponseCode;
import com.njmaomao.gj.pyot.common.Utils;
import com.njmaomao.gj.pyot.common.bean.BaseRequest;
import com.njmaomao.gj.pyot.common.bean.Response;
import com.njmaomao.gj.pyot.common.exception.SystemBizFail;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 校验BaseRequest,记录请求和响应日志
 *
 * @author hh
 *         2017年3月23日
 */
@Aspect
@Component
@Order(Integer.MIN_VALUE)
public class ControllerAspect {

    private static final Logger log = LoggerFactory.getLogger(ControllerAspect.class);

    /**
     * web入口作为切入点
     */
    @Pointcut("execution(public * com.njmaomao.gj.pyot.controller..*.*(..))")
    public void webLog() {
    }

    //TODO 兼容文件上传
    @Around("webLog()")
    public Object requestLog(ProceedingJoinPoint pjp){
        MethodSignature msig = (MethodSignature) pjp.getSignature();
        long startTime = System.currentTimeMillis();
        String seqNo = null;
        try {
            BaseRequest baseRequest = (BaseRequest)pjp.getArgs()[0];
            seqNo = baseRequest.getSeqNo();

            RequestContext.setCurrentRequest(baseRequest);
            MDC.put("seqNo", seqNo);

            log.info("{} with param: {}", msig.toShortString(), Utils.toJson(baseRequest));
            Object response = pjp.proceed ();
            log.info("{} spent {}ms, resp: {}", msig.toShortString(), System.currentTimeMillis() - startTime, Utils.toJson(response));
            return response;
        } catch (SystemBizFail sbf) {
            log.info("{} spent {}ms, SystemBizFail:{}-{}",msig.toShortString(), System.currentTimeMillis() - startTime, sbf.getCode(), sbf.getDesc());
            return Response.fail(seqNo, sbf.getCode(), sbf.getDesc());
        } catch (Throwable e) {
            log.error(e.getMessage(), e);
            log.info("{} spent {}ms, error:{}",msig.toShortString(), System.currentTimeMillis() - startTime, e.getMessage());
            return Response.fail(seqNo, ResponseCode.PAYTO.SYSTEM_ERROR.getCode(), ResponseCode.PAYTO.SYSTEM_ERROR.getDesc() + e.getMessage());
        } finally {
            RequestContext.removeCurrentRequest();
            MDC.clear();
        }
    }




}